﻿using NDF.DataAccess.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace NDF.DataAccess.EntityFramework
{ 
    /// <summary>
    /// 为 <see cref="System.Data.Entity.DbContext"/> 实例提供一组工具方法扩展。
    /// </summary>
    public static class DbContextExtensions
    {
        /// <summary>
        /// 获取基于当前数据库上下文环境的数据库访问基础组件对象 <see cref="NDF.DataAccess.Common.Database"/>。该对象可用于实现数据库的快速访问操作。
        /// </summary>
        /// <param name="context">表示当前数据库访问上下文 <see cref="System.Data.Entity.DbContext"/> 对象。</param>
        /// <returns>返回基于当前数据库上下文环境的数据库访问基础组件对象 <see cref="NDF.DataAccess.Common.Database"/>。</returns>
        public static Database GetNDFDatabase(this System.Data.Entity.DbContext context)
        {
            return context.Database.GetNDFDatabase();
        }



        /// <summary>
        /// 将在此上下文中所做的所有更改保存到基础数据库。<paramref name="validateOnSaveEnabled"/> 参数指示在调用 SaveChanges() 时，是否应自动验证所跟踪的实体。
        /// </summary>
        /// <param name="context">表示当前数据库访问上下文 <see cref="System.Data.Entity.DbContext"/> 对象。</param>
        /// <param name="validateOnSaveEnabled">指示在调用 SaveChanges() 时，是否应自动验证所跟踪的实体。</param>
        /// <returns>已写入基础数据库的对象的数目。</returns>
        public static int SaveChanges(this System.Data.Entity.DbContext context, bool validateOnSaveEnabled)
        {
            bool enabled = context.Configuration.ValidateOnSaveEnabled;
            context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled;
            try
            {
                context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled;
                return context.SaveChanges();
            }
            finally
            {
                context.Configuration.ValidateOnSaveEnabled = enabled;
            }
        }

        
        /// <summary>
        /// 将在此上下文中所做的所有更改异步保存到基础数据库。<paramref name="validateOnSaveEnabled"/> 参数指示在调用 SaveChanges() 时，是否应自动验证所跟踪的实体。
        /// </summary>
        /// <param name="context">表示当前数据库访问上下文 <see cref="System.Data.Entity.DbContext"/> 对象。</param>
        /// <param name="validateOnSaveEnabled">指示在调用 SaveChanges() 时，是否应自动验证所跟踪的实体。</param>
        /// <returns>表示异步保存操作的任务。任务结果包含已写入基础数据库的对象数目。</returns>
        public static Task<int> SaveChangesAsync(this System.Data.Entity.DbContext context, bool validateOnSaveEnabled)
        {
            bool enabled = context.Configuration.ValidateOnSaveEnabled;
            context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled;
            try
            {
                context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled;
                return context.SaveChangesAsync();
            }
            finally
            {
                context.Configuration.ValidateOnSaveEnabled = enabled;
            }
        }

        /// <summary>
        /// 将在此上下文中所做的所有更改异步保存到基础数据库。<paramref name="validateOnSaveEnabled"/> 参数指示在调用 SaveChanges() 时，是否应自动验证所跟踪的实体。
        /// </summary>
        /// <param name="context">表示当前数据库访问上下文 <see cref="System.Data.Entity.DbContext"/> 对象。</param>
        /// <param name="cancellationToken">等待任务完成期间要观察的 <see cref="CancellationToken"/>。</param>
        /// <param name="validateOnSaveEnabled">指示在调用 SaveChanges() 时，是否应自动验证所跟踪的实体。</param>
        /// <returns>表示异步保存操作的任务。任务结果包含已写入基础数据库的对象数目。</returns>
        public static Task<int> SaveChangesAsync(this System.Data.Entity.DbContext context, CancellationToken cancellationToken, bool validateOnSaveEnabled)
        {
            bool enabled = context.Configuration.ValidateOnSaveEnabled;
            context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled;
            try
            {
                context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled;
                return context.SaveChangesAsync(cancellationToken);
            }
            finally
            {
                context.Configuration.ValidateOnSaveEnabled = enabled;
            }
        }
    }
}
